package com.zongtui.fourinone.base;

import com.zongtui.fourinone.base.config.ConfigContext;
import com.zongtui.fourinone.utils.log.LogUtil;

import java.util.concurrent.*;

/**
 * 线程池.
 */
public class PoolExector //java.io.Closeable
{
    //线程池对象.
    private static ThreadPoolExecutor tpe;
    //可调度线程池对象.
    private static ScheduledThreadPoolExecutor stpe;

    //静态初始化块.
    public static ThreadPoolExecutor tpe() {
        //初始化线程池对象.
        if (tpe == null) {
            int corePoolSize = ConfigContext.getInitServices();
            int maximumPoolSize = ConfigContext.getMaxServices();
            long keepAliveTime = 3000;
            TimeUnit unit = TimeUnit.MILLISECONDS;
            BlockingQueue<Runnable> waitQueue = new ArrayBlockingQueue<>(2000);
            RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();//ThreadPoolExecutor.CallerRunsPolicy();
            tpe = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, waitQueue, handler);
        }
        return tpe;
    }

    static ScheduledThreadPoolExecutor stpe() {
        if (stpe == null) {
            int corePoolSize = ConfigContext.getInitServices();
            stpe = new ScheduledThreadPoolExecutor(corePoolSize);
        }
        return stpe;
    }

    /**
     * 执行命令.
     *
     * @param command      立刻执行的命令
     * @param delayCommand 后续执行的命令
     * @param delayTime    延时
     */
    protected static void execute(Runnable command, Runnable delayCommand, long delayTime) {
        tpe().execute(command);
        if (delayTime > 0)
            stpe().schedule(delayCommand, delayTime, TimeUnit.SECONDS);
    }

    /**
     * 关闭线程池.
     */
    public static void close() {
        if (tpe != null) {
            try {
                tpe.shutdown();
                tpe = null;
            } catch (SecurityException se) {
                LogUtil.info("[tpe]", "[close]", "[Error Exception:]", se);
            }
        }
        if (stpe != null) {
            try {
                stpe.shutdown();
                stpe = null;
            } catch (SecurityException se) {
                LogUtil.info("[stpe]", "[close]", "[Error Exception:]", se);
            }
        }
    }
}